home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Magnum One
/
Magnum One (Mid-American Digital) (Disc Manufacturing).iso
/
d12
/
grabtext.arc
/
PTXMAKE.C
< prev
next >
Wrap
Text File
|
1990-08-28
|
8KB
|
288 lines
/*
PTXMAKE.c by Bill Buckels 1990
written in AZTEC C small model
Supported Screen Mode is CGA COLOR TEXT Mode 4.
This is a companion utility to be used with BSAVED text images
and with my .PTX fileviewer PTXVU.EXE which was also written for fun.
I hope this code proves informative to those of you interested in
computer graphics.
This is also a limited example of applied "Run Length Encoding."
The IBM-PC 80- column text screen buffer-attribute pair arrangement
is suited to a 2-pass crunching algorithm.
In purely poetic terms....
Blocks of repeats occur on increments of every second byte so
I leapfrog through the file using the .PCX encoding technique
but I skip every second byte, and encode the ascuii value of
the text character only, then when I am done I make a second
pass to encode the bytes that have been skipped on first pass,
encoding the screen attributes.
Function:
converts a BASIC BSAVED .BSV IMAGE FILE (full screen CGA text)
to a .PTX ( similar to the ZSOFT .PCX format image file per the
VERSION 2.8 STANDARD without Color Map.)
*/
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <io.h>
#define SCREENSIZE 4000
FILE *ptxfile;
/* type conversion functions */
unsigned char lsb(unsigned int word){ return word &0xff;}
unsigned char msb(unsigned int word){ return word >>8;}
unsigned char ptxheader[128];
/* a microsoft compatible bsaved memory image format descriptor */
unsigned char BSV_header[7]={
'\xfd', /* ID Flag = file descriptor identifier bsaved file */
/* afew words about what BASIC does with this header */
/* and afew words about extending BASIC's ability to */
/* read and use BINARY files created in this manner. */
/* BASIC will use original segment and offset information */
/* to reload a memory image unless "DEF SEG" has been used */
/* and then an explicit offset is used as the second arg */
/* of the bload command. */
/* subsequently, once DEF SEG is invoked */
/* If an offset is specified without then */
/* first calling DEF SEG, The image will then be loaded to */
/* the segment specified in the last segment pointed to */
/* by the last call to DEF SEG. DEF SEG without args returns */
/* to DGROUP (the default data segment) and resets the thing.*/
/* we can also implement and store an array in memory by use of */
/* VARSEG and VARPTR to obtain the window for the array's */
/* memory location, i.e. override the defaults by windowing */
/* to the array base using DEF SEG = VARSEG(arrayname) then to */
/* fill the array we would use BLOAD bsaved.bsv, VARPTR(arrayname) */
/* using VARPTR to point to the offset from the memory base segment*/
'\x00', '\xb8', /* base address = MSB | LSB original segment */
'\x00', '\x00', /* offset from base = MSB | LSB original offset */
'\xA0', '\x0F' /* file size = MSB | LSB of bytes to be loaded + */
/* size of descriptors in bytes (8) */
};
unsigned char BSAVED_tailer[1]={ /* for reference only */
'\x1A'
};
int encline(inbuff,inlen)/* encodes a raw line and writes it out */
unsigned char *inbuff;
int inlen;
{
unsigned char this,last;
int srcindex,i;
register int total;
register unsigned char runcount;
total=0;
last = *(inbuff); runcount=1;
for(srcindex=1;srcindex!=inlen;srcindex++){
this= *(++inbuff);
if(this==last){
runcount++;
if(runcount==63){
if(!(i=encput(last,runcount)))
return(0);
total+=i;
runcount=0;
}
}
else{
if(runcount){
if(!(i=encput(last,runcount)))
return(0);
total+=i;
}
last=this;
runcount=1;
}
}
if(runcount){
if(!(i=encput(last,runcount)))
return(0);
return(total+i);
}
return (total);
}
int encput(byt,cnt) /* the writer for the encline function */
unsigned char byt,cnt;
{
if(cnt){
if((cnt==1)&& (0xc0 != (0xc0 &byt))){
if(EOF == fputc((int)byt,ptxfile))
return(0);
return(1);
}
else{
if(EOF ==fputc((int)0xc0|cnt,ptxfile))
return(0);
if(EOF ==fputc((int)byt,ptxfile))
return(0);
return(2);
}
}
return(0);
}
/* the zsoft technical reference manual details the */
/* structure of the following header */
int makeheader()
{
/* makes a standard header for a .PTX CGA FULL-SCREEN TEXT FILE */
/* since this info is not really intended for text mode, we fudge */
/* some portions of the info, but we try to be faithful as possible*/
int i;
unsigned char notzsoft=0,version=3,codetype=1,pixbits=16;
unsigned int xmin=0, ymin=0, xmax=79, ymax=24;
unsigned int hres=80, vres=25;
unsigned char no_planes=1;
unsigned int bytesperline=160;
for(i=0;i!=128;i++)ptxheader[i]=0;/* pad the header with nulls */
ptxheader[0]=notzsoft;
ptxheader[1]=version;
ptxheader[2]=codetype;
ptxheader[3]=pixbits;
ptxheader[4] =lsb(xmin);
ptxheader[5] =msb(xmin);
ptxheader[6] =lsb(ymin);
ptxheader[7] =msb(ymin);
ptxheader[8] =lsb(xmax);
ptxheader[9] =msb(xmax);
ptxheader[10]=lsb(ymax);
ptxheader[11]=msb(ymax);
ptxheader[12]=lsb(hres);
ptxheader[13]=msb(hres);
ptxheader[14]=lsb(vres);
ptxheader[15]=msb(vres);
ptxheader[65]=no_planes;
ptxheader[66]=lsb(bytesperline);
ptxheader[67]=msb(bytesperline);
return 0;
}
int BSV2PTX(char *name1, char *name2)
{
unsigned char *scratchbuffer;
unsigned char *buf;
unsigned char header[7];
int i,j,k;
int fh;
if((fh = open(name1,O_RDONLY)) == -1)return -1;
read(fh,header,7);
/* make sure that we have a valid BSAVED file format */
/* we can only check the first 2-bytes since it may */
/* have been made on the HERCULES */
if(header[0]!=BSV_header[0] || header[1]!=BSV_header[1])
{
close(fh);
return -2;
}
printf("BSV2PTX(C) Copyright by Bill Buckels\n\n");
printf("Input File: %s\n",name1);
printf("Output File: %s\n",name2);
scratchbuffer= malloc(SCREENSIZE);
buf=malloc(SCREENSIZE/2);
read(fh,scratchbuffer,SCREENSIZE);
close(fh);
/* seperate the attribute bytes */
/* use the two-tank system. */
makeheader();
ptxfile=fopen(name2,"w");
for(i=0;i!=128;i++)fputc(ptxheader[i],ptxfile);/* write the header */
for(k=0;k!=2;k++)
{
j=0;
for(i=k;i<SCREENSIZE;i+=2)
{
buf[j]=scratchbuffer[i];
j++;
}
encline(buf,SCREENSIZE/2);
}
fclose(ptxfile);
free(scratchbuffer);
free(buf);
printf("Done!\n");
return 0;
}
main(int argc,char *argv[])
{
char buffer[128];
char name1[128];
char name2[128];
char *wordptr;
int status=0;
switch(argc)
{
case 2: strcpy(buffer,argv[1]);
while(buffer[status]!=0)
{
if(buffer[status]=='.')buffer[status]=0;
else status++;
}
strcpy(name1,buffer);
strcat(name1,".BSV");
strcpy(name2,buffer);
strcat(name2,".PTX");
status=BSV2PTX(name1,name2);
if(status==0)exit(0);
default: printf("PTXMAKE(C) Copyright by Bill Buckels 1990\n");
printf(
"Usage : \"PTXMAKE [filename]\"\n");
printf(
"Converts .BSV BSAVED IMAGES to .PTX PACKED TEXT IMAGES.\n");
printf("CGA COLOR TEXT mode, screen dumps only.\n");
}
exit(0);
}